2019/11/30

Recent entries from same category

  1. RapidJSON や simdjson よりも速いC言語から使えるJSONライブラリ「yyjson」
  2. コメントも扱える高機能な C++ 向け JSON パーサ「jsoncpp」
  3. C++ で flask ライクなウェブサーバ「clask」書いた。
  4. C++ 用 SQLite3 ORM 「sqlite_orm」が便利。
  5. zsh で PATH に相対パスを含んだ場合にコマンドが補完できないのは意図的かどうか。

以前、mruby から TensorFlow Lite を扱う為の mrbgems、「mruby-tflite」を書きました。

Big Sky :: MRuby の TensorFlow Lite バインディングを書いた。

以前 TensorFlow Lite の Go バインディングを書いたのだけど Big Sky :: TensorFlow Lite の Go binding を書いた。 Google launche...

https://mattn.kaoriya.net/software/lang/c/20190417102631.htm

KaoriYa さんに Coral EdgeTPU をプレゼントして頂いたので、mruby-tflite を Coral EdgeTPU 対応する為の mrbgems を書きました。

GitHub - mattn/mruby-tflite-edgetpu
https://github.com/mattn/mruby-tflite-edgetpu

元の mruby-tflite とはソースを分離してあります。build_config.rb に以下の様に追加して頂くだけで EdgeTPU を扱える様になります。

conf.gem :github => 'mattn/mruby-tflite'
conf.gem :github => 'mattn/mruby-tflite-edgetpu'
conf.gem :github => 'kjunichi/mruby-webcam'
conf.gem :github => 'qtkmz/mruby-gd'

mruby-tflite と mruby-tflite-edgetpu を連携するには以下の様にインタプリタに対してオプション設定する必要があります。

#! ./bin/mruby

# オプションを生成
options = TfLite::InterpreterOptions.new

# Coral EdgeTPU のデバイス一覧から 0 番目を delegate として割り付け
options.add_delegate TfLite::EdgeTPU.new(TfLite::EdgeTPU.devices[0])

model = TfLite::Model.from_file 'mobilenet_ssd_v2_coco_quant_postprocess_edgetpu.tflite'
interpreter = TfLite::Interpreter.new(model, options)
interpreter.allocate_tensors
input = interpreter.input_tensor(0)
output2 = interpreter.output_tensor(1)
output3 = interpreter.output_tensor(2)
wanted_width = input.dim(1)
wanted_height = input.dim(2)
wanted_channel = input.dim(3)
data = Array.new(wanted_height * wanted_width * wanted_channel, 0)
labels = {}
File.read('coco_labels.txt').lines.each do |x|
  kv = x.split('  ')
  labels[kv[0].to_i] = kv[1].strip
end

cam = Webcam.new(ARGV[0]||0)
cam.set_size(wanted_width, wanted_height)
cam.each(true) {|img|
  decoded = GD::Image.new_from_jpeg_data(img)
  (0...wanted_width).each do |x|
    (0...wanted_height).each do |y|
      pixel = decoded.get_pixel(x, y)
      offset = (y * wanted_width + x) * wanted_channel
      data[offset..offset+2] = [decoded.red(pixel), decoded.green(pixel), decoded.blue(pixel)]
    end
  end
  decoded.destroy
  input.data = data
  interpreter.invoke
  result = []
  output3.data.each_with_index do |v, i|
    next if v < 0.6
    result.push([v, output2.data[i]])
  end
  result.sort{|a, b| b[0] <=> a[0] }.take(5).each_with_index do |v, i|
    s = v[0]
    i = v[1]
    puts "#{labels[i]} #{i} #{s}"
  end 
  puts "---"
}

現状、mruby には OpenCV の様に加工した MAT を表示できる mrbgems が存在しない為、kjunichi さんが作っておられる mruby-webcam で画像を取り込み、qtkmz さんの mruby-gd で画像を解析し、そこに何が映っているのかを端末に出力しているだけですが、今後 OpenCV の様な mrbgems が登場すれば mruby でもリアルタイムで画像を解析し、認識したオブジェクトに枠や名称を描画する事も出来る様になるかもしれません。

mruby-tflite-edgetpu
Posted at by